package com.ruoyix.weblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyix.weblog.config.VideoStorageConfig;
import com.ruoyix.weblog.domain.BlogVideos;
import com.ruoyix.weblog.mapper.BlogVideosMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
@RequiredArgsConstructor
@Service
@Slf4j
public class VideoConversionService {

    private final BlogVideosMapper blogVideosMapper;
    private final VideoStorageConfig webConfig;
    // 将视频文件转换为m3u8格式（Windows）
// 将视频文件转换为m3u8格式（Windows）
    @Async
    public void convertToM3U8ForWindows(String videoFilePath, String outputDir, long segmentDuration, String fileMd5) {
        String encKeyPath = webConfig.getVideo().getEncKeyinfo().getWindows();

        String[] command = {
            "ffmpeg",
            "-i", videoFilePath,
            "-c:v", "libx264",
            "-hls_time", String.valueOf(segmentDuration / 1000),
            "-hls_list_size", "0",
            "-hls_key_info_file", encKeyPath,
            "-f", "hls",
            outputDir + File.separator + "output.m3u8"
        };

        ProcessBuilder pb = new ProcessBuilder(command);
        pb.redirectErrorStream(true);
        readFfmpegLogs(fileMd5, pb);
    }

    @Async
    public void convertToM3U8ForLinux(String videoFilePath, String outputDir, long segmentDuration, String fileMd5) {
        String encKeyPath = webConfig.getVideo().getEncKeyinfo().getLinux();

        String[] command = {
            "ffmpeg",
            "-i", videoFilePath,
            "-c:v", "libx264",
            "-hls_time", String.valueOf(segmentDuration / 1000),
            "-hls_list_size", "0",
            "-hls_key_info_file", encKeyPath,
            "-f", "hls",
            outputDir + "/output.m3u8"
        };

        ProcessBuilder pb = new ProcessBuilder(command);
        readFfmpegLogs(fileMd5, pb);
    }

    private void updateStatus(String fileMd5) {
        LambdaQueryWrapper<BlogVideos> lqw = Wrappers.lambdaQuery();
        lqw.eq(BlogVideos::getMd5, fileMd5);
        BlogVideos blogVideos = blogVideosMapper.selectOne(lqw);
        if(ObjectUtils.isNotEmpty(blogVideos)){
            blogVideos.setStatus(1L);
            blogVideosMapper.updateById(blogVideos);
        }
    }

    private void readFfmpegLogs(String fileMd5, ProcessBuilder pb) {
        try {
            Process process = pb.start();
            new Thread(() -> {
                try (BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                    String line;
                    while ((line = stdInput.readLine()) != null) {
                        System.out.println("STDOUT: " + line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();

            new Thread(() -> {
                try (BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
                    String line;
                    while ((line = stdError.readLine()) != null) {
                        System.err.println("STDERR: " + line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
            process.waitFor();
            updateStatus(fileMd5);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}
